import { init, h} from 'snabbdom'
// 切换class
import { classModule } from 'snabbdom/modules/class'
// 设置DOM元素属性
import { propsModule } from 'snabbdom/modules/props'
// 处理元素样式，支持动画
import { styleModule } from 'snabbdom/modules/style'
// 监听事件
import { eventListenersModule } from 'snabbdom/modules/eventlisteners'

// 接收一个模块列表，并返回一个使用指定模块集的patch函数
let patch = init([classModule, propsModule, styleModule, eventListenersModule])

let vnode
let sortBy = 'rank' //排序方式
let totalHeight = 0 //list高度
let margin = 8 //list item margin
let rankIndex = 1 //item序号

// 源数据
let originalData = [
	{ rank: rankIndex, title: 'Fight', desc: 'An insomniac office' },
	{ rank: ++rankIndex, title: 'Angry', desc: 'Gandalf and Aragorn' },
	{ rank: ++rankIndex, title: 'Pulp', desc: 'bounty hunting' }
]

let data = Object.assign( [], originalData )

// 创建movies item Vnode
function movieView (movie) {
	return h('div.row', {
		key: movie.rank,
		style: {
			opacity: '0',
			transform: 'translate(-200px)',
			delayed: { transform:  `translateY(${movie.offset}px)`, opacity: '1' },
			remove: { opacity: '0', transform: `translateY(${movie.offset}px) translateX(200px)` }
		},
		// 挂载到DOM节点生命周期
		hook: { insert: (vnode) => { movie.elmHeight = vnode.elm.offsetHeight } },
	}, [
		h('div', { style: { fontWeight: 'bold' } }, movie.rank),
		h('div', movie.title),
		h('div', movie.desc),
		h('a.btn.rm-btn', { on: { click: [remove, movie] } }, '移除' ),
	])
}

// 渲染
// patch：对比两个Vnode，把Vnode差异渲染到真实DOM，并返回新的Vnode
function render () {
	data = data.reduce((acc, m) => {
		let last = acc[acc.length -1]
		m.offset = last ? last.offset + last.elmHeight + margin : margin
		return acc.concat(m)
	}, [])
	totalHeight = data[data.length - 1].offset + data[data.length -1].elmHeight
	vnode = patch(vnode, view(data))
}

// 虚拟DOM节点
function view (data) {
	return h('div', [
		h('h1', 'Top3 movies'),
		h('div', [ h('a.btn.add', { on: { click: add } }, '添加') ]),
		h('span', '排序'),
		h('span.btn-group', [
			h('a.btn.rank', { class: { active: sortBy === 'rank'}, on: { click: [changeSort, 'rank']}}, '排名'),
			h('a.btn.title', { class: { active: sortBy === 'title'}, on: { click: [changeSort, 'title']}}, '标题'),
			h('a.btn.desc', { class: { active: sortBy === 'desc'}, on: { click: [changeSort, 'desc']}}, '描述')
		]),
		h('div.list', { style: { height: totalHeight + 'px' }}, data.map(movieView) )
	])
}

// 初始的HTML文档被完全加载和解析完成之后触发
window.addEventListener('DOMContentLoaded', () => {
	let app = document.querySelector('#app')
	vnode = patch(app, view(data))	//先渲染dom
	render() //调整movie间距高度，重新渲染
})

// 排序
function changeSort (prop) {
	sortBy = prop
	data.sort((a, b) => {
		if (a[prop] > b[prop]) {
		  return 1
		}
		if (a[prop] < b[prop]) {
		  return -1
		}
		return 0
	})
	render()
}

// 添加Item
function add () {
	let item = originalData[Math.floor(Math.random() * 3)] //从源数据中随机一条
	data.push({
		rank: ++rankIndex, //改变序号
		title: item.title,
		desc: item.desc
	})
	render()
}

// 移除Item
function remove (movie) {
	data = data.filter(function(item) {
		return item !== movie //过滤移除的项
	})
	render()
}